// Copyright (c) 2004 Dmitry Shuklin. All rights reserved.
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;

namespace Cerebrum.Direct3D.Forms.Docking
{
	/// <summary>
	/// Summary description for Panel.
	/// </summary>
	public class Panel : Cerebrum.Direct3D.Forms.Control 
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Panel(System.ComponentModel.IContainer container)
		{
			///
			/// Required for Windows.Forms Class Composition Designer support
			///
			container.Add(this);
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		public Panel()
		{
			///
			/// Required for Windows.Forms Class Composition Designer support
			///
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}


		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
		}
		#endregion


		protected float m_Amount = 1;
		public float Amount
		{
			get
			{
				return m_Amount;
			}
			set
			{
				if(m_Amount != value)
				{
					m_Amount = value;
					this.Parent_Resize(null, null);
				}
			}
		}

		internal override void SetParentCore(Control parent)
		{
			bool newParent = false;
			if(this.m_Parent!=parent)
			{
				if(this.m_Parent!=null)
				{
					this.m_Parent.Resize -= new EventHandler(this.Parent_Resize);
				}
				newParent = true;
			}
			base.SetParentCore (parent);
			if(newParent)
			{
				if(this.m_Parent!=null)
				{
					this.m_Parent.Resize += new EventHandler(this.Parent_Resize);
					this.UpdateAmount();
				}
			}
		}

		protected void UpdateAmount()
		{
			if(this.m_Parent!=null)
			{
				switch (this.m_Dock)
				{
					case System.Windows.Forms.DockStyle.Bottom:
					case System.Windows.Forms.DockStyle.Top:
					{
#warning "NaN when parent.size==0"
						float v = this.m_Parent.DisplayRectangle.Height;
						if( v > 0.5f )
						{
							this.m_Amount = this.m_DisplayRectangle.Height / v;
						}
						break;
					}
					case System.Windows.Forms.DockStyle.Right:
					case System.Windows.Forms.DockStyle.Left:
					{
						float v = this.m_Parent.DisplayRectangle.Width;
						if( v > 0.5f )
						{
							this.m_Amount = this.m_DisplayRectangle.Width / v;
						}
						break;
					}
				}
			}
		}

		protected internal override void OnResize(EventArgs e)
		{
			this.UpdateAmount();
			base.OnResize (e);
		}


		private void Parent_Resize(object sender, EventArgs e)
		{
			switch (this.m_Dock)
			{
				case System.Windows.Forms.DockStyle.Bottom:
				case System.Windows.Forms.DockStyle.Top:
				{
					this.SetBoundsCore(0, 0, 0, this.Parent.DisplayRectangle.Height * m_Amount, System.Windows.Forms.BoundsSpecified.Height);
					break;
				}
				case System.Windows.Forms.DockStyle.Right:
				case System.Windows.Forms.DockStyle.Left:
				{
					this.SetBoundsCore(0, 0, this.Parent.DisplayRectangle.Width * m_Amount, 0, System.Windows.Forms.BoundsSpecified.Width);
					break;
				}
			}
		}

		protected Resizer m_Resizer;
		public Resizer GetResizer()
		{
			if(m_Resizer!=null && this.Controls.Contains(m_Resizer))
			{
				return m_Resizer;
			}
			else
			{
				return null;
			}
		}

		protected override void OnDockChanged(EventArgs e)
		{
			
			System.Windows.Forms.DockStyle _ndock = System.Windows.Forms.DockStyle.None;
			System.Windows.Forms.Cursor _cursor = System.Windows.Forms.Cursors.Default;

			switch(this.Dock)
			{
				case System.Windows.Forms.DockStyle.Bottom:
				{
					_ndock = System.Windows.Forms.DockStyle.Top;
					_cursor = System.Windows.Forms.Cursors.HSplit;
					break;
				}
				case System.Windows.Forms.DockStyle.Right:
				{
					_ndock = System.Windows.Forms.DockStyle.Left;
					_cursor = System.Windows.Forms.Cursors.VSplit;
					break;
				}
				case System.Windows.Forms.DockStyle.Top:
				{
					_ndock = System.Windows.Forms.DockStyle.Bottom;
					_cursor = System.Windows.Forms.Cursors.HSplit;
					break;
 
				}
				case System.Windows.Forms.DockStyle.Left:
				{
					_ndock = System.Windows.Forms.DockStyle.Right;
					_cursor = System.Windows.Forms.Cursors.VSplit;
					break;
 
				}
			}
			if(_ndock!=System.Windows.Forms.DockStyle.None)
			{
				if(m_Resizer==null)
				{
					m_Resizer = new Resizer();
				}
					m_Resizer.Dock = _ndock;
					m_Resizer.Cursor = _cursor;
					m_Resizer.Size = new System.Drawing.SizeF(3, 3);

				int index = this.Controls.IndexOf(m_Resizer);
				int lasti = this.Controls.Count-1 ;
				if(index < 0)
				{
					this.Controls.Add(m_Resizer);
				}
				else if(lasti != index)
				{
					this.Controls.SetChildIndex(m_Resizer, lasti);
				}
			}
			else
			{
				if(m_Resizer!=null)
				{
					this.Controls.Remove(m_Resizer);
				}
			}

			this.UpdateAmount();

			base.OnDockChanged(e);
		}

	}
}
